Программирование сетевых приложений

Средства языка для организации работы в сети

Программирование сетевых приложений

Содержание лекции

  • Распределенная обработка данных
  • Основы работы в сети
  • Клиент-серверная архитектура
  • Proxy-сервера
  • Internet-адресация
  • Сетевые классы и интерфейсы
  • Обзор сокетов
  • TCP/IP клиенты и серверы
  • Дейтаграммы (UDP)
  • Использование URL
  • Практические примеры на Qt
Средства языка для организации работы в сети
Программирование сетевых приложений

Распределенная обработка данных

Понятие распределенной системы

  • Совокупность независимых компьютеров, представляемых пользователю как единая система
  • Компоненты взаимодействуют через сеть
  • Общие характеристики:
    • Масштабируемость
    • Отказоустойчивость
    • Прозрачность доступа
    • Конкурентный доступ к ресурсам
Средства языка для организации работы в сети
Программирование сетевых приложений

Модели сетевой архитектуры

Модель OSI vs TCP/IP

(Подробное описание моделей OSI и TCP/IP рассмотрено в лекции 2. Ниже — краткая справка.)

OSI TCP/IP Протоколы Роль в программировании
7. Прикладной Прикладной HTTP, FTP, DNS, SMTP Основной уровень для разработчика
6. Представления SSL/TLS, JPEG, JSON Кодирование/шифрование данных
5. Сеансовый NetBIOS, RPC Управление сессиями
4. Транспортный Транспортный TCP, UDP Сокеты, QTcpSocket, QUdpSocket
3. Сетевой Интернет IP, ICMP, ARP Маршрутизация, адресация
2. Канальный Сетевой доступа Ethernet, Wi-Fi Драйверы, NIC
1. Физический Электрические сигналы Кабели, оптоволокно

Для программиста сетевых приложений ключевые уровни: Транспортный (TCP/UDP сокеты) и Прикладной (HTTP, RPC).

Средства языка для организации работы в сети
Программирование сетевых приложений

Принципы маршрутизации и коммутации

Маршрутизация (Routing) на 3 уровне

  • Определение оптимального пути для пакетов
  • Использование таблиц маршрутизации
  • Протоколы динамической маршрутизации (OSPF, BGP)
  • Логическая адресация (IP-адреса)
Средства языка для организации работы в сети
Программирование сетевых приложений

Коммутация (Switching) на 2 уровне

  • Передача кадров между сегментами сети
  • Использование MAC-адресов
  • Создание таблиц коммутации
  • Виртуальные LAN (VLAN)
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы коммутации:

  1. Канальная коммутация - установление выделенного канала
  2. Пакетная коммутация - передача независимых пакетов
  3. Сообщечная коммутация - передача цельных сообщений
Средства языка для организации работы в сети
Программирование сетевых приложений

Качество обслуживания (QoS - Quality of Service)

Параметры QoS:

  • Пропускная способность (Bandwidth) - максимальная скорость передачи
  • Задержка (Latency) - время передачи данных
  • Джиттер (Jitter) - изменение задержки
  • Потери пакетов (Packet Loss) - процент потерянных пакетов
Средства языка для организации работы в сети
Программирование сетевых приложений

Механизмы QoS:

  • Приоритизация трафика (Traffic Prioritization)
  • Контроль полосы пропускания (Bandwidth Management)
  • Управление очередями (Queue Management)
  • Формирование трафика (Traffic Shaping)
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы сетевых устройств по уровням OSI

Устройство Уровни OSI Функции
Концентратор (Hub) 1 (Физический) Повторение сигналов
Мост (Bridge) 2 (Канальный) Соединение сетевых сегментов
Коммутатор (Switch) 2 (Канальный) Коммутация кадров по MAC-адресам
Маршрутизатор (Router) 3 (Сетевой) Маршрутизация пакетов по IP-адресам
Шлюз (Gateway) 4-7 (Транспортный и выше) Протокольная трансляция
Межсетевой экран (Firewall) 3-4 (Сетевой и транспортный) Фильтрация трафика
Брандмауэр приложений 7 (Прикладной) Фильтрация на уровне приложений
Средства языка для организации работы в сети
Программирование сетевых приложений

Клиент-серверная архитектура

Основные принципы

Клиент-серверная архитектура - это модель организации сетевого взаимодействия, при которой одна сторона (клиент) инициирует запрос, а другая сторона (сервер) обрабатывает этот запрос и возвращает ответ.

Роли участников:

  • Клиент - инициатор запроса, потребитель услуг
  • Сервер - исполнитель запроса, поставщик услуг
  • Точка взаимодействия - сокет (socket), через который происходит обмен данными
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы клиент-серверных архитектур

1. Двухуровневая архитектура (2-tier)

Клиент ←→ Сервер базы данных
  • Клиент содержит бизнес-логику и пользовательский интерфейс
  • Сервер управляет данными
  • Примеры: традиционные настольные приложения
Средства языка для организации работы в сети
Программирование сетевых приложений

2. Трехуровневая архитектура (3-tier)

Клиент ←→ Сервер приложений ←→ Сервер базы данных
  • Клиент - только пользовательский интерфейс
  • Сервер приложений - бизнес-логика
  • Сервер базы данных - хранение данных
  • Преимущества: лучшая масштабируемость и безопасность
Средства языка для организации работы в сети
Программирование сетевых приложений

3. Многоуровневая архитектура (n-tier)

Клиент ←→ Веб-сервер ←→ Сервер приложений ←→ Сервер базы данных
  • Дополнительные уровни для балансировки нагрузки, кэширования и т.д.
  • Современные веб-приложения и микросервисы
Средства языка для организации работы в сети
Программирование сетевых приложений

Принципы работы клиент-серверного взаимодействия

Этапы взаимодействия:

  1. Инициализация сервера
    • Создание сокета
    • Привязка к адресу и порту
    • Перевод в режим прослушивания
    • Ожидание подключений
  2. Подключение клиента
    • Создание сокета клиента
    • Установление соединения с сервером
    • Проверка успешности подключения

  1. Обмен данными
    • Клиент отправляет запрос
    • Сервер обрабатывает запрос
    • Сервер отправляет ответ
    • Клиент получает ответ
  2. Завершение сеанса
    • Закрытие соединения
    • Освобождение ресурсов
Средства языка для организации работы в сети
Программирование сетевых приложений

Состояния соединения:

  • CLOSED - соединение закрыто
  • LISTEN - сервер ожидает подключений
  • SYN_SENT - клиент отправил запрос на соединение
  • SYN_RECEIVED - сервер получил запрос
  • ESTABLISHED - соединение установлено
  • FIN_WAIT - инициация закрытия соединения
  • CLOSE_WAIT - ожидание закрытия
  • TIME_WAIT - ожидание перед полным закрытием
Средства языка для организации работы в сети
Программирование сетевых приложений

Преимущества клиент-серверной архитектуры

1. Централизованное управление данными

  • Все данные хранятся на сервере
  • Единая точка контроля и администрирования
  • Упрощенное резервное копирование и восстановление
  • Централизованная система безопасности

2. Масштабируемость

  • Возможность увеличения мощности сервера
  • Кластеризация и балансировка нагрузки
  • Разделение функций между несколькими серверами
  • Горизонтальное и вертикальное масштабирование

3. Безопасность

  • Контроль доступа на уровне сервера
  • Защита данных от несанкционированного доступа
  • Возможность шифрования канала связи
  • Аудит и логирование действий

4. Разделение ответственности

  • Четкое разделение функций между клиентом и сервером
  • Упрощение разработки и поддержки
  • Возможность независимого обновления компонентов
  • Специализация разработчиков

5. Эффективность использования ресурсов

  • Централизованные вычислительные мощности
  • Экономия ресурсов клиентских устройств
  • Оптимизация работы с данными
  • Кэширование и предобработка данных
Средства языка для организации работы в сети
Программирование сетевых приложений

Недостатки клиент-серверной архитектуры

1. Зависимость от сервера

  • Одиночная точка отказа
  • Необходимость высокой доступности сервера
  • Сложность обеспечения отказоустойчивости

2. Сложность администрирования

  • Требуются квалифицированные администраторы
  • Необходимость постоянного мониторинга
  • Сложность диагностики проблем
Средства языка для организации работы в сети
Программирование сетевых приложений

3. Пропускная способность сети

  • Ограничение скорости передачи данных
  • Зависимость от качества сетевого соединения
  • Возможные задержки при передаче данных
Средства языка для организации работы в сети
Программирование сетевых приложений

Паттерны проектирования для клиент-серверных приложений

1. Паттерн "Запрос-Ответ" (Request-Response)

  • Синхронное взаимодействие
  • Клиент ждет ответа перед продолжением работы
  • Примеры: HTTP, RPC

2. Паттерн "Односторонняя передача" (One-way)

  • Асинхронное взаимодействие
  • Клиент не ждет подтверждения
  • Примеры: UDP, сообщения очередей

3. Паттерн "Публикация-Подписка" (Publish-Subscribe)

  • Клиенты подписываются на события
  • Сервер рассылает уведомления подписчикам
  • Примеры: MQTT, WebSocket, системы очередей

4. Паттерн "Долгое опросное соединение" (Long Polling)

  • Клиент устанавливает длительное соединение
  • Сервер держит соединение открытым до появления данных
  • Используется для реализации push-уведомлений
Средства языка для организации работы в сети
Программирование сетевых приложений

Примеры клиент-серверных приложений

1. Веб-приложения

  • Браузер (клиент) ←→ Веб-сервер
  • Используют протокол HTTP/HTTPS
  • Запросы на получение веб-страниц и ресурсов

2. Электронная почта

  • Почтовый клиент ←→ Почтовый сервер
  • Протоколы: SMTP, POP3, IMAP
  • Отправка и получение сообщений

3. Файловые сервисы

  • FTP-клиент ←→ FTP-сервер
  • Загрузка и выгрузка файлов
  • Управление файловой системой на сервере

4. Системы обмена сообщениями

  • Мессенджер (клиент) ←→ Сервер обмена сообщениями
  • Передача текстовых и мультимедийных сообщений
  • Групповые чаты и конференции
Средства языка для организации работы в сети
Программирование сетевых приложений

Безопасность в клиент-серверных приложениях

1. Аутентификация
  • Проверка подлинности клиента
  • Методы: пароли, токены, сертификаты
  • Многофакторная аутентификация
2. Авторизация
  • Контроль доступа к ресурсам
  • Определение прав и привилегий
  • Ролевая модель доступа
3. Шифрование
  • Защита данных при передаче
  • Протоколы: SSL/TLS, SSH
  • Симметричное и асимметричное шифрование
4. Защита от атак
  • Защита от перехвата данных (sniffing)
  • Защита от подмены данных (spoofing)
  • Защита от отказа в обслуживании (DoS)
  • Проверка входных данных
Средства языка для организации работы в сети
Программирование сетевых приложений

Internet-адресация

Основы IP-адресации

IP-адресация - это система логических адресов, используемая для идентификации устройств в сети и обеспечения маршрутизации данных между ними. IP-адреса работают на сетевом уровне (3 уровень) модели OSI.

Принципы IP-адресации:

  • Каждое устройство в сети имеет уникальный IP-адрес
  • IP-адрес состоит из двух частей: сетевой и хостовой
  • Адреса используются для маршрутизации пакетов
  • Поддерживаются два основных стандарта: IPv4 и IPv6
Средства языка для организации работы в сети
Программирование сетевых приложений

IPv4 (Internet Protocol версия 4)

Структура IPv4-адреса

  • Размер: 32 бита (4 байта)
  • Формат записи: четыре десятичных числа, разделенные точками (например, 192.168.1.1)
  • Диапазон значений: от 0.0.0.0 до 255.255.255.255
  • Количество возможных адресов: 2³² = 4,294,967,296 адресов
Средства языка для организации работы в сети
Программирование сетевых приложений

Классовая адресация IPv4

Класс Диапазон первого октета Маска по умолчанию Количество сетей Количество хостов
A 1-126 255.0.0.0 126 16,777,214
B 128-191 255.255.0.0 16,384 65,534
C 192-223 255.255.255.0 2,097,152 254
D 224-239 - Мультикаст -
E 240-255 - Экспериментальные -
Средства языка для организации работы в сети
Программирование сетевых приложений

Специальные IPv4-адреса

Адрес/Диапазон Назначение
0.0.0.0 Неопределенный адрес, адрес по умолчанию
127.0.0.0/8 Адреса обратной петли (loopback)
10.0.0.0/8 Частная сеть класса A
172.16.0.0/12 Частная сеть класса B
192.168.0.0/16 Частная сеть класса C
169.254.0.0/16 Автоматические частные IP-адреса (APIPA)
255.255.255.255 Широковещательный адрес
Средства языка для организации работы в сети
Программирование сетевых приложений

Подсети (Subnetting)

Маска подсети - это 32-битное число, которое определяет, какая часть IP-адреса относится к сети, а какая - к хосту.

Формулы подсетей:

  • Количество подсетей = 2ⁿ, где n - количество заимствованных битов
  • Количество хостов в подсети = 2ᵐ - 2, где m - количество битов хоста

CIDR-нотация (Classless Inter-Domain Routing):

  • Формат: IP-адрес/префикс (например, 192.168.1.0/24)
  • Префикс указывает количество битов сетевой части
Средства языка для организации работы в сети
Программирование сетевых приложений

Примеры CIDR:

  • /24 = 255.255.255.0 = 256 адресов (254 хоста)
  • /25 = 255.255.255.128 = 128 адресов (126 хостов)
  • /26 = 255.255.255.192 = 64 адреса (62 хоста)
  • /27 = 255.255.255.224 = 32 адреса (30 хостов)
Средства языка для организации работы в сети
Программирование сетевых приложений

IPv6 (Internet Protocol версия 6)

Необходимость IPv6

  • Исчерпание адресного пространства IPv4 - рост числа устройств в Интернете
  • Улучшенная маршрутизация - иерархическая структура адресов
  • Безопасность - встроенная поддержка IPsec
  • Автоконфигурация - упрощенное подключение устройств
  • Производительность - оптимизированная структура заголовков
Средства языка для организации работы в сети
Программирование сетевых приложений

Структура IPv6-адреса

  • Размер: 128 бит (16 байтов)
  • Формат записи: восемь групп по четыре шестнадцатеричных цифры, разделенных двоеточиями
  • Пример: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • Сокращенная запись: 2001:db8:85a3::8a2e:370:7334
  • Количество возможных адресов: 2¹²⁸ ≈ 3.4 × 10³⁸ адресов
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы IPv6-адресов

Тип Диапазон Назначение
Unicast (одноадресный) 2000::/3 Обычные адреса узлов
Multicast (групповой) FF00::/8 Групповые адреса
Anycast (любойадресный) - Адрес ближайшего узла
Link-local FE80::/10 Локальная сеть
Site-local FEC0::/10 Частная сеть (устарел)
Loopback ::1/128 Обратная петля
Unspecified ::/128 Неопределенный адрес
Средства языка для организации работы в сети
Программирование сетевых приложений

Форматы IPv6-адресов

Глобальный unicast-адрес:

| 48 бит (глобальный префикс) | 16 бит (подсеть) | 64 бита (интерфейс) |

Link-local адрес:

FE80:: + 54 нулевых бита + 64-битный идентификатор интерфейса

IPv4-совместимый адрес:

::ffff:192.168.1.1 (последние 32 бита - IPv4-адрес)
Средства языка для организации работы в сети
Программирование сетевых приложений

Порты (Ports)

Основы портов

Порт - это 16-битное число, используемое для идентификации процессов или служб в пределах одного IP-адреса.

  • Диапазон портов: 0-65535 (2¹⁶ возможных портов)
  • Размер: 16 бит
  • Формат: TCP/UDP порт
  • Назначение: мультиплексирование соединений
Средства языка для организации работы в сети
Программирование сетевых приложений

Классификация портов

Диапазон Категория Назначение Примеры
0-1023 Зарезервированные (Well-known) Системные службы HTTP (80), FTP (21), SSH (22)
1024-49151 Зарегистрированные (Registered) Прикладные службы MySQL (3306), PostgreSQL (5432)
49152-65535 Динамические (Dynamic/Private) Временные соединения Клиентские порты
Средства языка для организации работы в сети
Программирование сетевых приложений

Назначение портов

  • Идентификация служб - каждая служба имеет стандартный порт
  • Мультиплексирование - несколько соединений на одном IP-адресе
  • Безопасность - контроль доступа к службам
  • Маршрутизация - направление трафика к нужному процессу
Средства языка для организации работы в сети
Программирование сетевых приложений

DNS (Domain Name System)

Назначение DNS

DNS - это распределенная система доменных имен, которая преобразует удобочитаемые доменные имена (например, www.example.com) в IP-адреса (например, 93.184.216.34).

Средства языка для организации работы в сети
Программирование сетевых приложений

Иерархия DNS

Корневые серверы (.)
    ↓
Серверы верхнего уровня (.com, .org, .ru и т.д.)
    ↓
Серверы второго уровня (example.com)
    ↓
Локальные DNS-серверы
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы DNS-записей

Тип записи Назначение Пример
A IPv4-адрес example.com → 93.184.216.34
AAAA IPv6-адрес example.com → 2001:db8::1
CNAME Псевдоним (alias) www.example.com → example.com
MX Почтовый сервер mail.example.com
NS DNS-сервер ns1.example.com
PTR Обратная запись 34.216.184.93.in-addr.arpa → example.com
TXT Текстовая информация SPF, DKIM записи
SRV Сервис _sip._tcp.example.com
Средства языка для организации работы в сети
Программирование сетевых приложений

Процесс разрешения DNS

  1. Локальный кэш - проверка локального кэша браузера и ОС
  2. Локальный DNS-сервер - запрос к настроенному DNS-серверу
  3. Рекурсивный запрос - локальный сервер делает запросы от имени клиента
  4. Корневые серверы - получение информации о серверах верхнего уровня
  5. Серверы верхнего уровня - получение информации об авторитетных серверах
  6. Авторитетные серверы - получение конечного IP-адреса
Средства языка для организации работы в сети
Программирование сетевых приложений

Кэширование DNS

  • Время жизни записи (TTL) - определяет, как долго запись хранится в кэше
  • Иерархическое кэширование - кэш на разных уровнях (браузер, ОС, локальный DNS)
  • Обновление кэша - периодическое обновление записей по истечении TTL
Средства языка для организации работы в сети
Программирование сетевых приложений

Маршрутизация (Routing)

Основы маршрутизации

Маршрутизация - это процесс определения оптимального пути для передачи пакетов от источника к назначению.

Средства языка для организации работы в сети
Программирование сетевых приложений

Типы маршрутизации

  1. Статическая маршрутизация

    • Маршруты задаются вручную администратором
    • Не требует дополнительных ресурсов
    • Подходит для простых сетей
    • Не адаптируется к изменениям в сети
  2. Динамическая маршрутизация

    • Маршруты определяются автоматически
    • Используются протоколы маршрутизации
    • Адаптируется к изменениям в сети
    • Требует дополнительных ресурсов
Средства языка для организации работы в сети
Программирование сетевых приложений

Протоколы маршрутизации

Протокол Тип Метрика Область применения
RIP Distance Vector Количество хопов Малые сети
OSPF Link State Стоимость связи Средние и большие сети
BGP Path Vector Политика, AS-путь Интернет
EIGRP Hybrid Составная метрика Сети Cisco
Средства языка для организации работы в сети
Программирование сетевых приложений

Таблица маршрутизации

Содержит информацию о:

  • Сети назначения
  • Маске подсети
  • Шлюзе (Gateway)
  • Интерфейсе
  • Метрике маршрута
  • Приоритете маршрута
Средства языка для организации работы в сети
Программирование сетевых приложений

NAT (Network Address Translation)

Назначение NAT

NAT - это технология преобразования IP-адресов, позволяющая нескольким устройствам в частной сети использовать один публичный IP-адрес для доступа в Интернет.

Средства языка для организации работы в сети
Программирование сетевых приложений

Типы NAT

  1. Статический NAT (One-to-One)

    • Один частный IP-адрес → один публичный IP-адрес
    • Используется для серверов, требующих постоянного адреса
  2. Динамический NAT (Many-to-Many)

    • Пул частных IP-адресов → пул публичных IP-адресов
    • Адреса назначаются по мере необходимости
  3. PAT (Port Address Translation) / NAT Overload

    • Множество частных IP-адресов → один публичный IP-адрес
    • Используются порты для различения соединений
    • Наиболее распространенный тип NAT
Средства языка для организации работы в сети
Программирование сетевых приложений

Преимущества NAT:

  • Экономия публичных IP-адресов
  • Безопасность - скрытие внутренней структуры сети
  • Гибкость - возможность изменения внутренней адресации
  • Совместимость - работа с различными протоколами

Недостатки NAT:

  • Сложность для некоторых протоколов (FTP, VoIP)
  • Проблемы с безопасностью при неправильной настройке
  • Ограничения для пиринговых приложений
  • Дополнительная задержка при обработке пакетов
Средства языка для организации работы в сети
Программирование сетевых приложений

Обзор сокетов

Что такое сокет?

Сокет (socket) - это абстрактный механизм межпроцессного взаимодействия, представляющий собой конечную точку сетевого соединения. Сокет является основой всех сетевых коммуникаций в современных операционных системах.

Средства языка для организации работы в сети
Программирование сетевых приложений

Основные характеристики сокетов:

  • Точка взаимодействия между процессами (как локальными, так и удаленными)
  • Комбинация IP-адреса и порта (например, 192.168.1.100:8080)
  • Предоставляет интерфейс для сетевого взаимодействия через системные вызовы
  • Поддерживает как однонаправленную, так и двунаправленную передачу данных
Средства языка для организации работы в сети
Программирование сетевых приложений

Архитектура сокетов:

Приложение → Сокет API → Транспортный уровень (TCP/UDP) → Сетевой уровень (IP) → Канальный уровень

История и стандарты

  • Первоначально разработаны в BSD Unix (1983 год)
  • Стандартизированы в POSIX.1-2001
  • Реализованы во всех современных ОС (Windows, Linux, macOS)
  • Являются универсальным интерфейсом для сетевого программирования
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы сокетов по семейству адресов

1. AF_INET (IPv4)

  • Используются для сетевого взаимодействия через протокол IPv4
  • Адрес: 32-битный IP-адрес + 16-битный порт
  • Наиболее распространенный тип

2. AF_INET6 (IPv6)

  • Поддерживают протокол IPv6
  • Адрес: 128-битный IP-адрес + 16-битный порт
  • Обеспечивают больший адресный простор

3. AF_UNIX (AF_LOCAL)

  • Используются для локального межпроцессного взаимодействия
  • Не требуют сетевого стека
  • Обеспечивают высокую производительность
Средства языка для организации работы в сети
Программирование сетевых приложений

Типы сокетов по типу взаимодействия

1. SOCK_STREAM (потоковые сокеты)

  • Протокол: TCP (Transmission Control Protocol)
  • Характеристики:
    • Надежная доставка данных
    • Упорядоченная передача (без потерь и дублирования)
    • Установление соединения (трехэтапное рукопожатие)
    • Двунаправленный поток данных
  • Применение: HTTP, FTP, SMTP, SSH и другие протоколы, требующие надежности
Средства языка для организации работы в сети
Программирование сетевых приложений

2. SOCK_DGRAM (дейтаграммные сокеты)

  • Протокол: UDP (User Datagram Protocol)
  • Характеристики:
    • Без установления соединения
    • Не гарантирует доставку
    • Не гарантирует порядок доставки
    • Минимальные накладные расходы
  • Применение: DNS, DHCP, VoIP, онлайн-игры, потоковое видео
Средства языка для организации работы в сети
Программирование сетевых приложений

3. SOCK_RAW (сырые сокеты)

  • Прямой доступ к сетевому уровню
  • Возможность формировать собственные заголовки протоколов
  • Требуют привилегированного доступа (root/administrator)
  • Используются для создания сетевых утилит (ping, traceroute)
Средства языка для организации работы в сети
Программирование сетевых приложений

Жизненный цикл сокета

1. Создание сокета

int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

2. Привязка к адресу (для сервера)

bind(socket_fd, (struct sockaddr*)&address, sizeof(address));
Средства языка для организации работы в сети
Программирование сетевых приложений

3. Установление соединения

  • Клиент: connect()
  • Сервер: listen()accept()

4. Обмен данными

  • send() / recv() для TCP
  • sendto() / recvfrom() для UDP
Средства языка для организации работы в сети
Программирование сетевых приложений

5. Закрытие соединения

close(socket_fd);  // Unix/Linux
closesocket(socket_fd);  // Windows
Средства языка для организации работы в сети
Программирование сетевых приложений

Системные вызовы для работы с сокетами

Основные функции:

  • socket() - создание сокета
  • bind() - привязка к локальному адресу
  • listen() - перевод в режим прослушивания
  • accept() - принятие входящего соединения
  • connect() - установление соединения
  • send()/recv() - передача данных (TCP)
  • sendto()/recvfrom() - передача данных (UDP)
  • close() - закрытие сокета
Средства языка для организации работы в сети
Программирование сетевых приложений

Дополнительные функции:

  • select() - мультиплексирование ввода/вывода
  • setsockopt() - установка параметров сокета
  • getsockopt() - получение параметров сокета
  • getsockname() - получение локального адреса
  • getpeername() - получение удаленного адреса
Средства языка для организации работы в сети
Программирование сетевых приложений

Параметры сокетов (Socket Options)

Важные опции:

  • SO_REUSEADDR - повторное использование локального адреса
  • SO_KEEPALIVE - поддержание соединения активным
  • SO_RCVBUF/SO_SNDBUF - размер буферов приема/передачи
  • TCP_NODELAY - отключение алгоритма Нейгла
  • SO_LINGER - управление закрытием соединения
Средства языка для организации работы в сети
Программирование сетевых приложений

Блокирующие и неблокирующие режимы

Блокирующий режим (по умолчанию):

  • Операции ввода/вывода блокируют выполнение программы
  • Простота программирования
  • Неэффективность при работе с несколькими соединениями

Неблокирующий режим:

  • Операции возвращаются немедленно
  • Требует использования механизмов опроса (select, poll, epoll)
  • Эффективен для высоконагруженных приложений
Средства языка для организации работы в сети
Программирование сетевых приложений

Преимущества использования сокетов

  1. Универсальность - стандартный интерфейс для всех платформ
  2. Гибкость - поддержка различных протоколов и типов соединений
  3. Контроль - полный контроль над процессом передачи данных
  4. Производительность - прямой доступ к транспортному уровню
  5. Совместимость - работа между различными операционными системами
Средства языка для организации работы в сети
Программирование сетевых приложений

Недостатки и ограничения

  1. Сложность - необходимость ручного управления многими аспектами
  2. Безопасность - отсутствие встроенных механизмов шифрования
  3. Переносимость - различия в реализации между платформами
  4. Отладка - сложность диагностики сетевых проблем
Средства языка для организации работы в сети
Программирование сетевых приложений

Теория сетевых протоколов

TCP (Transmission Control Protocol)

Основные характеристики TCP:

  • Надежная доставка - гарантирует доставку всех данных
  • Упорядоченная передача - данные приходят в правильном порядке
  • Контроль потока - предотвращает перегрузку получателя
  • Контроль перегрузки - адаптируется к состоянию сети
  • Двунаправленный поток данных - полный дуплекс
Средства языка для организации работы в сети
Программирование сетевых приложений

Структура TCP-сегмента:

[Заголовок TCP | Данные]
  • Порты источника и назначения (16 бит каждый)
  • Номер последовательности (32 бита)
  • Номер подтверждения (32 бита)
  • Флаги управления (SYN, ACK, FIN, RST, PSH, URG)
  • Размер окна (16 бит) - контроль потока
  • Контрольная сумма (16 бит)
Средства языка для организации работы в сети
Программирование сетевых приложений

Процесс установления TCP-соединения (трехэтапное рукопожатие):

  1. SYN: клиент отправляет запрос на соединение
  2. SYN-ACK: сервер подтверждает получение и отправляет свой запрос
  3. ACK: клиент подтверждает получение
Клиент                    Сервер
  |                        |
  |-------- SYN -------->  |
  |                        |
  |<----- SYN-ACK -------  |
  |                        |
  |-------- ACK -------->  |
  |                        |
Средства языка для организации работы в сети
Программирование сетевых приложений

Процесс завершения TCP-соединения (четырехэтапное завершение):

  1. FIN: инициатор отправляет запрос на завершение
  2. ACK: получатель подтверждает получение
  3. FIN: получатель отправляет запрос на завершение
  4. ACK: инициатор подтверждает получение

Алгоритмы и механизмы TCP:

  • Алгоритм Нейгла - объединение маленьких пакетов
  • Алгоритм медленного старта - постепенное увеличение скорости передачи
  • Алгоритм устранения перегрузки - реакция на потери пакетов
  • Таймеры повторной передачи - контроль времени ожидания подтверждений
Средства языка для организации работы в сети
Программирование сетевых приложений

UDP (User Datagram Protocol)

Основные характеристики UDP:

  • Без установления соединения - данные отправляются немедленно
  • Ненадежная доставка - нет гарантии доставки
  • Без упорядочивания - пакеты могут прийти в неправильном порядке
  • Минимальные накладные расходы - всего 8 байт заголовка
  • Границы сообщений сохраняются - датаграммы не разбиваются
Средства языка для организации работы в сети
Программирование сетевых приложений

Структура UDP-датаграммы:

[Заголовок UDP (8 байт) | Данные]
  • Порт источника (16 бит)
  • Порт назначения (16 бит)
  • Длина датаграммы (16 бит)
  • Контрольная сумма (16 бит, опционально)

Преимущества UDP:

  • Низкая задержка - отсутствие установления соединения
  • Высокая скорость - минимальная обработка
  • Возможность широковещательной передачи (broadcast)
  • Гибкость - приложение само контролирует надежность
Средства языка для организации работы в сети
Программирование сетевых приложений

Приложения, использующие UDP:

  • DNS (порт 53) - система доменных имен
  • DHCP (порты 67/68) - динамическая конфигурация хостов
  • VoIP - голосовая связь по IP
  • Видеостриминг - онлайн-трансляции
  • Онлайн-игры - передача игровых данных
  • SNMP - сетевое управление
Средства языка для организации работы в сети
Программирование сетевых приложений

Сравнение TCP и UDP

Характеристика TCP UDP
Надежность Гарантированная Не гарантирована
Упорядочивание Сохраняется порядок Порядок не гарантирован
Соединение Устанавливается Не устанавливается
Скорость Медленнее Быстрее
Размер заголовка 20+ байт 8 байт
Потоковая передача Поддерживается Только сообщения
Контроль перегрузки Есть Нет
Широковещательность Нет Да
Средства языка для организации работы в сети
Программирование сетевых приложений

Сетевые классы Qt

Основные классы для работы с сетью

  • QTcpSocket - TCP-клиент
  • QTcpServer - TCP-сервер
  • QUdpSocket - UDP-сокет
  • QHostAddress - IP-адрес
  • QNetworkAccessManager - HTTP-клиент
  • QNetworkRequest - HTTP-запрос
  • QNetworkReply - HTTP-ответ
Средства языка для организации работы в сети
Программирование сетевых приложений

TCP-клиент на Qt

#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>

class TcpClient : public QObject {
    Q_OBJECT
    
private:
    QTcpSocket* socket;
    
public:
    TcpClient(QObject* parent = nullptr) : QObject(parent) {
        socket = new QTcpSocket(this);
        
        connect(socket, &QTcpSocket::connected, this, &TcpClient::onConnected);
        connect(socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
        connect(socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
        
        // Подключение к серверу
        socket->connectToHost(QHostAddress("127.0.0.1"), 8080);
    }
    
private slots:
    void onConnected() {
        qDebug() << "Подключено к серверу";
        socket->write("Hello, Server!");
    }
    
    void onReadyRead() {
        QByteArray data = socket->readAll();
        qDebug() << "Получено:" << data;
    }
    
    void onDisconnected() {
        qDebug() << "Отключено от сервера";
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

TCP-сервер на Qt

#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>

class TcpServer : public QObject {
    Q_OBJECT
    
private:
    QTcpServer* server;
    QList<QTcpSocket*> clients;
    
public:
    TcpServer(QObject* parent = nullptr) : QObject(parent) {
        server = new QTcpServer(this);
        
        connect(server, &QTcpServer::newConnection, 
                this, &TcpServer::onNewConnection);
        
        if (server->listen(QHostAddress::Any, 8080)) {
            qDebug() << "Сервер запущен на порту 8080";
        } else {
            qDebug() << "Ошибка запуска сервера:" << server->errorString();
        }
    }
    
private slots:
    void onNewConnection() {
        QTcpSocket* clientSocket = server->nextPendingConnection();
        clients.append(clientSocket);
        
        connect(clientSocket, &QTcpSocket::readyRead, 
                this, &TcpServer::onReadyRead);
        connect(clientSocket, &QTcpSocket::disconnected, 
                this, &TcpServer::onDisconnected);
        
        qDebug() << "Новый клиент подключен:" 
                 << clientSocket->peerAddress().toString();
    }
    
    void onReadyRead() {
        QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
        QByteArray data = client->readAll();
        qDebug() << "Получено от клиента:" << data;
        
        // Отправка ответа всем клиентам
        for (QTcpSocket* c : clients) {
            c->write("Сообщение получено: " + data);
        }
    }
    
    void onDisconnected() {
        QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
        clients.removeAll(client);
        client->deleteLater();
        qDebug() << "Клиент отключен";
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

UDP/Дейтаграммы на Qt

#include <QUdpSocket>
#include <QHostAddress>
#include <QDebug>

class UdpServer : public QObject {
    Q_OBJECT
    
private:
    QUdpSocket* udpSocket;
    
public:
    UdpServer(QObject* parent = nullptr) : QObject(parent) {
        udpSocket = new QUdpSocket(this);
        
        if (udpSocket->bind(QHostAddress::Any, 1234)) {
            qDebug() << "UDP сервер запущен на порту 1234";
            connect(udpSocket, &QUdpSocket::readyRead, 
                    this, &UdpServer::onReadyRead);
        }
    }
    
private slots:
    void onReadyRead() {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            
            udpSocket->readDatagram(datagram.data(), datagram.size(),
                                   &sender, &senderPort);
            
            qDebug() << "Получено от" << sender.toString() 
                     << ":" << senderPort << "-" << datagram;
            
            // Отправка ответа
            udpSocket->writeDatagram("Ответ получен", sender, senderPort);
        }
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

UDP-клиент на Qt

#include <QUdpSocket>
#include <QHostAddress>
#include <QDebug>

class UdpClient : public QObject {
    Q_OBJECT
    
private:
    QUdpSocket* udpSocket;
    
public:
    UdpClient(QObject* parent = nullptr) : QObject(parent) {
        udpSocket = new QUdpSocket(this);
        
        connect(udpSocket, &QUdpSocket::readyRead, 
                this, &UdpClient::onReadyRead);
        
        // Отправка сообщения
        sendMessage("Hello UDP Server!");
    }
    
    void sendMessage(const QString& message) {
        QByteArray datagram = message.toUtf8();
        QHostAddress serverAddress("127.0.0.1");
        quint16 serverPort = 1234;
        
        udpSocket->writeDatagram(datagram, serverAddress, serverPort);
        qDebug() << "Отправлено:" << message;
    }
    
private slots:
    void onReadyRead() {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            
            udpSocket->readDatagram(datagram.data(), datagram.size(),
                                   &sender, &senderPort);
            
            qDebug() << "Получено от" << sender.toString() 
                     << ":" << senderPort << "-" << datagram;
        }
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

HTTP-клиент на Qt

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QDebug>

class HttpClient : public QObject {
    Q_OBJECT
    
private:
    QNetworkAccessManager* manager;
    
public:
    HttpClient(QObject* parent = nullptr) : QObject(parent) {
        manager = new QNetworkAccessManager(this);
        
        connect(manager, &QNetworkAccessManager::finished,
                this, &HttpClient::onRequestFinished);
        
        // GET запрос
        getRequest("https://api.github.com/users/octocat");
        
        // POST запрос
        postRequest("https://httpbin.org/post", "{\"key\":\"value\"}");
    }
    
    void getRequest(const QString& url) {
        QNetworkRequest request(QUrl(url));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        
        manager->get(request);
    }
    
    void postRequest(const QString& url, const QByteArray& data) {
        QNetworkRequest request(QUrl(url));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        
        manager->post(request, data);
    }
    
private slots:
    void onRequestFinished(QNetworkReply* reply) {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray response = reply->readAll();
            qDebug() << "Ответ:" << response;
        } else {
            qDebug() << "Ошибка:" << reply->errorString();
        }
        
        reply->deleteLater();
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Proxy-сервер на Qt

#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>

class ProxyServer : public QObject {
    Q_OBJECT
    
private:
    QTcpServer* server;
    QString targetHost;
    quint16 targetPort;
    
public:
    ProxyServer(const QString& targetHost, quint16 targetPort, 
                QObject* parent = nullptr) : QObject(parent) {
        this->targetHost = targetHost;
        this->targetPort = targetPort;
        
        server = new QTcpServer(this);
        connect(server, &QTcpServer::newConnection, 
                this, &ProxyServer::onNewConnection);
        
        if (server->listen(QHostAddress::Any, 8888)) {
            qDebug() << "Прокси-сервер запущен на порту 8888";
        }
    }
    
private slots:
    void onNewConnection() {
        QTcpSocket* clientSocket = server->nextPendingConnection();
        QTcpSocket* targetSocket = new QTcpSocket(this);
        
        // Подключение к целевому серверу
        targetSocket->connectToHost(targetHost, targetPort);
        
        // Проксирование данных
        connect(clientSocket, &QTcpSocket::readyRead, [=]() {
            if (targetSocket->state() == QAbstractSocket::ConnectedState) {
                targetSocket->write(clientSocket->readAll());
            }
        });
        
        connect(targetSocket, &QTcpSocket::readyRead, [=]() {
            clientSocket->write(targetSocket->readAll());
        });
        
        connect(clientSocket, &QTcpSocket::disconnected, [=]() {
            targetSocket->disconnectFromHost();
            clientSocket->deleteLater();
            targetSocket->deleteLater();
        });
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Работа с URL в Qt

#include <QUrl>
#include <QUrlQuery>
#include <QDebug>

class UrlExample {
public:
    static void demonstrateUrlParsing() {
        // Создание URL
        QUrl url("https://api.example.com:8080/users?name=John&age=25#section");
        
        // Разбор URL
        qDebug() << "Схема:" << url.scheme();      // https
        qDebug() << "Хост:" << url.host();         // api.example.com
        qDebug() << "Порт:" << url.port();         // 8080
        qDebug() << "Путь:" << url.path();         // /users
        qDebug() << "Запрос:" << url.query();      // name=John&age=25
        qDebug() << "Фрагмент:" << url.fragment(); // section
        
        // Работа с параметрами запроса
        QUrlQuery query(url);
        qDebug() << "Параметры:";
        for (auto it = query.queryItems().begin(); 
             it != query.queryItems().end(); ++it) {
            qDebug() << "  " << it->first << "=" << it->second;
        }
        
        // Создание URL с параметрами
        QUrl newUrl("https://example.com/search");
        QUrlQuery newQuery;
        newQuery.addQueryItem("q", "Qt network");
        newQuery.addQueryItem("page", "1");
        newUrl.setQuery(newQuery);
        
        qDebug() << "Сформированный URL:" << newUrl.toString();
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Зарезервированные сокеты (Well-Known Ports)

IANA (Internet Assigned Numbers Authority) выделяет три диапазона портов:

Диапазон Назначение Примеры
0-1023 (Well-Known) Зарезервированы для системных служб 20/21 (FTP), 22 (SSH), 80 (HTTP), 443 (HTTPS)
1024-49151 (Registered) Зарегистрированные для приложений 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis)
49152-65535 (Dynamic) Динамические/частные порты Временные порты для клиентских соединений

Правила использования портов

  • Порты 0-1023 требуют прав администратора (root/Administrator) для привязки (bind)
  • Для пользовательских серверов используйте порты из диапазона 1024-49151
  • Порт 0 — означает автоматический выбор свободного порта ОС
  • /etc/services (Linux) — реестр зарезервированных служб

Наиболее часто используемые порты в сетевом программировании

Порт Протокол Описание
80 HTTP Веб-серверы (без шифрования)
443 HTTPS Веб-серверы (SSL/TLS)
22 SSH Безопасное удалённое управление
21 FTP Передача файлов
3306 MySQL База данных MySQL
5432 PostgreSQL База данных PostgreSQL
6379 Redis In-memory хранилище
8080 HTTP (alt) Альтернативный HTTP-порт (часто используется для тестов)
Средства языка для организации работы в сети
Программирование сетевых приложений

Обработка ошибок в сетевых приложениях

#include <QTcpSocket>
#include <QAbstractSocket>
#include <QDebug>

class NetworkErrorHandler : public QObject {
    Q_OBJECT
    
public:
    static QString getErrorDescription(QAbstractSocket::SocketError error) {
        switch (error) {
            case QAbstractSocket::ConnectionRefusedError:
                return "Соединение отклонено";
            case QAbstractSocket::RemoteHostClosedError:
                return "Удаленный хост закрыл соединение";
            case QAbstractSocket::HostNotFoundError:
                return "Хост не найден";
            case QAbstractSocket::SocketAccessError:
                return "Нет доступа к сокету";
            case QAbstractSocket::SocketResourceError:
                return "Не хватает системных ресурсов";
            case QAbstractSocket::SocketTimeoutError:
                return "Таймаут соединения";
            case QAbstractSocket::DatagramTooLargeError:
                return "Датаграмма слишком велика";
            case QAbstractSocket::NetworkError:
                return "Ошибка сети";
            case QAbstractSocket::AddressInUseError:
                return "Адрес уже используется";
            default:
                return "Неизвестная ошибка";
        }
    }
    
    static void handleNetworkError(QAbstractSocket* socket) {
        connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
                [=](QAbstractSocket::SocketError socketError) {
            qDebug() << "Ошибка сети:" << getErrorDescription(socketError);
            qDebug() << "Детали:" << socket->errorString();
        });
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Асинхронная работа с сетью

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QEventLoop>
#include <QTimer>

class AsyncNetworkExample {
public:
    // Синхронный запрос (блокирующий)
    static QByteArray syncRequest(const QString& url) {
        QNetworkAccessManager manager;
        QNetworkRequest request(QUrl(url));
        
        QNetworkReply* reply = manager.get(request);
        
        QEventLoop loop;
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        
        // Таймаут 5 секунд
        QTimer::singleShot(5000, &loop, &QEventLoop::quit);
        
        loop.exec();
        
        if (reply->error() == QNetworkReply::NoError) {
            return reply->readAll();
        } else {
            return QByteArray();
        }
    }
    
    // Асинхронный запрос (неблокирующий)
    static void asyncRequest(const QString& url) {
        QNetworkAccessManager* manager = new QNetworkAccessManager();
        QNetworkRequest request(QUrl(url));
        
        QNetworkReply* reply = manager->get(request);
        
        QObject::connect(reply, &QNetworkReply::finished, [=]() {
            if (reply->error() == QNetworkReply::NoError) {
                qDebug() << "Ответ получен:" << reply->readAll();
            } else {
                qDebug() << "Ошибка:" << reply->errorString();
            }
            
            reply->deleteLater();
            manager->deleteLater();
        });
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Безопасность в сетевых приложениях

#include <QSslSocket>
#include <QSslCertificate>
#include <QSslKey>

class SecureNetworkExample {
public:
    static void createSecureConnection() {
        QSslSocket* socket = new QSslSocket();
        
        // Настройка SSL/TLS
        connect(socket, &QSslSocket::encrypted, []() {
            qDebug() << "Соединение зашифровано";
        });
        
        connect(socket, &QSslSocket::sslErrors, [](const QList<QSslError>& errors) {
            for (const QSslError& error : errors) {
                qDebug() << "SSL ошибка:" << error.errorString();
            }
        });
        
        // Подключение к HTTPS серверу
        socket->connectToHostEncrypted("api.github.com", 443);
        
        // Проверка сертификата
        connect(socket, &QSslSocket::peerVerifyError, [](const QSslError& error) {
            qDebug() << "Ошибка проверки сертификата:" << error.errorString();
        });
        
        socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
    }
    
    static void loadCertificates() {
        QSslSocket* socket = new QSslSocket();
        
        // Загрузка клиентского сертификата
        QList<QSslCertificate> certificates = QSslCertificate::fromPath("client.crt");
        if (!certificates.isEmpty()) {
            socket->setLocalCertificate(certificates.first());
        }
        
        // Загрузка приватного ключа
        QFile keyFile("client.key");
        if (keyFile.open(QIODevice::ReadOnly)) {
            QSslKey privateKey(keyFile.readAll(), QSsl::Rsa);
            socket->setPrivateKey(privateKey);
        }
    }
};
Средства языка для организации работы в сети
Программирование сетевых приложений

Производительность и оптимизация

Советы по оптимизации сетевых приложений

  1. Используйте буферы нужного размера

    socket->setReadBufferSize(64 * 1024); // 64KB буфер
    
  2. Объединяйте маленькие сообщения

    socket->write(message1);
    socket->write(message2);
    socket->flush(); // Принудительная отправка
    
Средства языка для организации работы в сети
Программирование сетевых приложений
  1. Используйте сжатие данных

    QByteArray compressed = qCompress(data, 9); // максимальное сжатие
    
  2. Реализуйте пул соединений

    class ConnectionPool {
        QList<QTcpSocket*> availableSockets;
        // Управление пулом соединений
    };
    
Средства языка для организации работы в сети
Программирование сетевых приложений

Лучшие практики

1. Обработка ошибок

  • Всегда проверяйте возвращаемые значения
  • Используйте сигналы об ошибках
  • Логируйте важные события

2. Безопасность

  • Используйте шифрование (SSL/TLS)
  • Проверяйте входные данные
  • Реализуйте аутентификацию
Средства языка для организации работы в сети
Программирование сетевых приложений

3. Производительность

  • Используйте асинхронные операции
  • Реализуйте кэширование
  • Оптимизируйте размер пакетов

4. Масштабируемость

  • Используйте многопоточность
  • Реализуйте балансировку нагрузки
  • Применяйте паттерны проектирования
Средства языка для организации работы в сети
Программирование сетевых приложений

Резюме

Ключевые концепции

  • Сокеты - основа сетевого взаимодействия
  • Qt Network - мощный инструментарий для сетевого программирования
  • TCP vs UDP - выбор протокола в зависимости от задачи
  • Безопасность - важный аспект сетевых приложений
  • Асинхронность - ключ к отзывчивым приложениям

Дальнейшее изучение

  • Многопоточные сетевые приложения
  • Веб-сокеты (WebSockets)
  • Пиринговые сети (P2P)
  • Облачные технологии
  • Микросервисная архитектура
Средства языка для организации работы в сети
Программирование сетевых приложений

Вопросы для самопроверки

  1. В чем различие между TCP и UDP?
  2. Какие классы Qt используются для HTTP-запросов?
  3. Как обрабатывать сетевые ошибки?
  4. Что такое прокси-сервер и как его реализовать?
  5. Как обеспечить безопасность сетевого соединения?
Средства языка для организации работы в сети

Заметки докладчика: - Это КЛЮЧЕВАЯ лекция курса — 6 академических часов. - Лекция очень объёмная (1758 строк), рекомендуется разбить на два занятия: - Занятие 1: теория — OSI, IP-адресация, DNS, TCP/UDP, клиент-серверная архитектура. - Занятие 2: практика — Qt TCP-сервер/клиент, UDP, HTTP, proxy-сервер. - При ограниченном времени фокусируйтесь на уровнях 4 (Транспортный) и 7 (Прикладной) — именно с ними работают программисты.

Заметки докладчика: - Содержание OSI пересекается с лекцией 02. Если студенты уже изучали — быстрый обзор и переход далее. - Программистам важны в первую очередь уровни 4 (Транспортный — TCP/UDP) и 7 (Прикладной — HTTP, DNS). - Остальные уровни — для понимания контекста, но не для повседневной работы. - QoS и устройства по уровням — можно сократить при нехватке времени.

Заметки докладчика: - Студенты обязаны знать: приватные диапазоны (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), loopback (127.0.0.1), localhost. - IPv6 всё важнее — покажите реальные IPv6-адреса (ifconfig / ip addr на машине). - В Qt: QHostAddress обрабатывает оба формата автоматически. - Частый вопрос на экзамене: «какой адрес у localhost?» — 127.0.0.1 (IPv4), ::1 (IPv6).

Заметки докладчика: - DNS-разрешение — первый шаг любого сетевого соединения. Без DNS клиент не знает, куда подключаться. - В Qt: QHostInfo::lookupHost() — асинхронное DNS-разрешение через сигналы/слоты. - Кэширование DNS снижает задержку: браузер → ОС → локальный DNS-сервер → рекурсивный запрос. - DNS — иерархическая распределённая база данных, не централизованный сервер. - Продемонстрируйте: nslookup, dig, или QHostInfo::fromName() в Qt.

Заметки докладчика: - Трёхэтапное рукопожатие SYN → SYN-ACK → ACK нужно ЗНАТЬ НАИЗУСТЬ — частый вопрос на экзамене. - Покажите захват в Wireshark — студенты должны увидеть эти пакеты своими глазами. - В Qt: QTcpSocket::connectToHost() инкапсулирует всё рукопожатие — программисту не нужно управлять им вручную. - Завершение: 4-этапное (FIN→ACK→FIN→ACK) — тоже стоит упомянуть.

Заметки докладчика: - Это основа для лабораторной работы (Echo-сервер). Убедитесь, что студенты разобрались. - Ключевой паттерн: сервер слушает → принимает → создаёт обработчик на клиента → сигналы/слоты для асинхронного I/O. - deleteLater() — критически важно для предотвращения утечек памяти. Объясните, почему нельзя вызвать delete напрямую (событийный цикл может обращаться к объекту после удаления). - Для усложнения: добавьте хранение списка клиентов, рассылку сообщений (чат).

Заметки докладчика: - Proxy-сервер — хороший пример двунаправленной пересылки данных. - Читаем от клиента → пишем на сервер, читаем с сервера → пишем клиенту. - Оба направления должны обрабатываться асинхронно (сигналы/слоты). - Обратите внимание на deleteLater() для обоих сокетов при отключении клиента. - Упражнение для студентов: добавить логирование пересылаемых данных, подсчёт байт.

Заметки докладчика: - Зарезервированные сокеты (well-known ports) — обязательный пункт учебной программы. - Студенты часто путают: bind() к порту <1024 на Linux требует sudo. В курсовых проектах использовать порты > 1024. - Порт 8080 — де-факто стандарт для тестовых серверов в учебных заведениях. - QTcpServer::listen(QHostAddress::Any, 0) — передаём 0, ОС выберет свободный порт, можно узнать через serverPort().

Заметки докладчика: Ожидаемые ответы на вопросы самопроверки: 1. TCP — надёжный, с установлением соединения, упорядоченная доставка. UDP — ненадёжный, без соединения, быстрый, сохраняет границы сообщений. 2. QNetworkAccessManager — основной класс. QNetworkRequest для формирования запроса, QNetworkReply для получения ответа. 3. Обработка сигнала errorOccurred (или QOverload<QAbstractSocket::SocketError>), проверка QNetworkReply::NetworkError, информативные сообщения для пользователя. 4. Прокси-сервер — промежуточный узел между клиентом и целевым сервером. Реализация: QTcpServer принимает подключения, создаёт QTcpSocket к целевому серверу, пересылает данные в обоих направлениях через сигналы/слоты. 5. Использование HTTPS (QSslSocket), валидация SSL-сертификатов, аутентификация, не хранить пароли в открытом виде, проверка входных данных.